package org.wisigoth.chat.swing.splash;

import java.awt.Image;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JWindow;

/**
 * Un splash screen permettant d'afficher une image pendant un delay 
 * minimum.
 * @author dtfs-tof
 *
 */


public class ImageSplash extends JWindow implements Splash {
	
	/**
	 * Image a afficher
	 */
	private Image image;
	
	/**
	 * Delay minimum d'affichage en millisecondes
	 */
	private int minDelay;
	
	/**
	 * enregistre le moment ou a ete affiche le splash
	 */
	private long launchTime;
	
	/**
	 * Cree un splash permettant d'afficher une image pendant un delay minimum
	 * exprime en millisec.
	 * 
	 * @param image image affichee par le splash
	 * @param minDelay delai minimum d'affichage du splash en millisec
	 */
	public ImageSplash(Image image, int minDelay){
		if(image == null){
			throw new IllegalArgumentException("Null image");
		}
		if (minDelay < 0){
			throw new IllegalArgumentException("Negative minDelay");
		}
		this.image = image;
		this.minDelay = minDelay;
		initComponents();
	}

	/**
	 * Initialise le splash en ajoutant l'image et en gerant la taille du splash
	 */
	private void initComponents() {
		JLabel imageLabel = new JLabel(new ImageIcon(image));
		this.add(imageLabel);
		this.pack();
		this.setLocationRelativeTo(imageLabel);

	}

	/**
	 * Constructeur permettant d'initialiser le splash a partir du nom d'une image et avec une duree minimum
	 * 
	 * @param image affichee par le splash
	 * @param minDelay delai minimum d'affichage du splash
	 */
	public ImageSplash(String image, int minDelay){
		if(image == null){
			throw new IllegalArgumentException("Null image");
		}
		if (minDelay < 0){
			throw new IllegalArgumentException("Negative minDelay");
		}
		
		try {
			this.image = loadImage(image);
		} catch (IOException e) {
			throw new IllegalArgumentException("Failed to load image from classpath: " + image);
		}
		this.minDelay = minDelay;
		initComponents();
	}
	
	/** 
	 * Methode chargeant l'image a partir d'un nom de fichier
	 * @param image nom du fichier contenant l'image
	 * @return l'objet image correspondant au nom du fichier passe en parametre
	 * @throws IOException si l'image n'est pas trouvee dans le classpath
	 */
	private static Image loadImage (String image) throws IOException{
		URL imageResource = ImageSplash.class.getResource(image);
		return ImageIO.read(imageResource);
	}
	
	@Override
	public void setVisible(boolean visible) {
		if(visible){
			showSplash();
		}else{
			hideSplash();
		}
	}
	
	private void hideSplash() {
		if(!this.isVisible()){
			return;
		}
		if(System.currentTimeMillis()-this.launchTime > this.minDelay){
			super.setVisible(false);
		}else{
			try {
				
				Thread.currentThread().sleep(System.currentTimeMillis()-launchTime);		
			} catch (InterruptedException e) {
				//nothing to do
			} finally {
				super.setVisible(false);
			}
		}
	}

	private void showSplash() {
		if(this.isVisible()){
			return;
		}
		
		super.setVisible(true);
		this.launchTime = System.currentTimeMillis();
	}

	public static void main(String[] args) throws Exception {
		ImageSplash splash = new ImageSplash("/images/splash.jpg", 5000);
		splash.setVisible(true);
		
		System.out.println("Application initialization...");
		Thread.currentThread().sleep(10000);
		System.out.println("Application initialized");
		splash.setVisible(false);
		splash.dispose();
		
		System.exit(0);
		
	}

}
